/**
 *  This file is part of MunchLevel.
 *
 *  MunchLevel is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  MunchLevel is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with MunchLevel.  If not, see <http://www.gnu.org/licenses/>.
 */
package com.munchlevel.view;

import java.util.List;

import android.content.Context;
import android.content.SharedPreferences;
import android.graphics.Bitmap;
import android.preference.PreferenceManager;
import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.util.AttributeSet;
import android.view.GestureDetector;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnLongClickListener;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;

import com.gandulf.guilib.util.Debug;
import com.munchlevel.MunchLevelApplication;
import com.munchlevel.MyPreferenceActivity;
import com.munchlevel.R;
import com.munchlevel.data.PlayerInfo;
import com.munchlevel.fragment.PlayerFragment;

public class PlayerLayout extends BasePlayerLayout implements OnClickListener, OnLongClickListener {

	private EditText editPlayerName;
	private TextView playerClassRace;

	private Tooltip nameTip, genderTip, gearTip;

	private ImageView profileView;

	private PlayerFragment playerFragment = null;

	private GestureDetector gestureDetector = new GestureDetector(new GestureDetector.SimpleOnGestureListener() {

		public void onLongPress(MotionEvent e) {
			((Tooltip) findViewById(R.id.tt_genderswitch)).hide();
			setMale(!playerinfo.isMale());
		};

		public boolean onSingleTapConfirmed(MotionEvent e) {
			playerFragment.startFight();
			return true;
		};

	});

	public PlayerLayout(Context context, AttributeSet attrs) {
		this(context, attrs, 0);
	}

	public PlayerLayout(Context context) {
		this(context, null);
	}

	public PlayerLayout(Context context, AttributeSet attrs, int defStyle) {
		this(context, attrs, defStyle, null);
	}

	public PlayerLayout(Context context, AttributeSet attrs, int defStyle, PlayerInfo playerInfo) {
		super(context, attrs, defStyle, playerInfo);
	}

	public void onSharedPreferenceChanged(SharedPreferences pref, String key) {

		if (key == null || MyPreferenceActivity.KEY_GEAR_COUNTER.equals(key)) {
			boolean gearVisible = pref.getBoolean(MyPreferenceActivity.KEY_GEAR_COUNTER, true);
			setGearCounterVisibility(gearVisible);
		}

		if (key == null || MyPreferenceActivity.KEY_PROFILE_PICTURE.equals(key)) {
			boolean cameraVisible = pref.getBoolean(MyPreferenceActivity.KEY_PROFILE_PICTURE, true);
			setProfilePictureVisibility(cameraVisible);
		}

		if (key == null || MyPreferenceActivity.KEY_CLASS_RACE.equals(key)) {
			boolean raceVisible = pref.getBoolean(MyPreferenceActivity.KEY_CLASS_RACE, true);
			if (raceVisible)
				findViewById(R.id.tv_playerrace).setVisibility(View.VISIBLE);
			else
				findViewById(R.id.tv_playerrace).setVisibility(View.GONE);
		}

		if (key == null || MyPreferenceActivity.KEY_MAX_LEVEL.equals(key)) {
			// -- level
			int max;
			try {
				max = Integer.valueOf(pref.getString(MyPreferenceActivity.KEY_MAX_LEVEL, "10"));
			} catch (NumberFormatException e) {
				max = 10;
			}
			setMaximumLevel(max);
		}

	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see android.view.View#onTouchEvent(android.view.MotionEvent)
	 */
	@Override
	public boolean onTouchEvent(MotionEvent event) {
		gestureDetector.onTouchEvent(event);
		return true;
	}

	@Override
	protected void onFinishInflate() {
		super.onFinishInflate();

		if (gearCounter != null) {
			gearCounter.setOnClickListener(this);
			gearCounter.setOnLongClickListener(this);
		}
		try {
			genderTip = ((Tooltip) findViewById(R.id.tt_genderswitch));
			nameTip = ((Tooltip) findViewById(R.id.tt_namechange));
			gearTip = ((Tooltip) findViewById(R.id.tt_gear_counter));

			setOnLongClickListener(this);

			View playerView = findViewById(R.id.tv_playername);

			playerClassRace = (TextView) findViewById(R.id.tv_playerrace);
			MunchLevelApplication.applyFont(playerClassRace);
			SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(getContext());

			if (preferences.getBoolean(MyPreferenceActivity.KEY_CLASS_RACE, true)) {
				playerClassRace.setVisibility(View.VISIBLE);
			} else {
				playerClassRace.setVisibility(View.GONE);
			}

			if (playerView instanceof EditText) {
				editPlayerName = (EditText) playerView;
				MunchLevelApplication.applyFont(editPlayerName);
				editPlayerName.setHorizontallyScrolling(true);
				editPlayerName.setSingleLine();
				editPlayerName.setSelected(true);
				editPlayerName.setFocusable(false);
				editPlayerName.setOnTouchListener(new OnTouchListener() {

					@Override
					public boolean onTouch(View v, MotionEvent event) {
						nameTip.hide();
						editPlayerName.setFocusable(true);
						editPlayerName.requestFocusFromTouch();
						return false;
					}
				});

				editPlayerName.addTextChangedListener(new TextWatcher() {

					@Override
					public void onTextChanged(CharSequence s, int start, int before, int count) {

					}

					@Override
					public void beforeTextChanged(CharSequence s, int start, int count, int after) {

					}

					@Override
					public void afterTextChanged(Editable s) {
						String oldName = playerinfo.getName();
						String newName = s.toString();

						if (!TextUtils.equals(oldName, newName)) {

							playerinfo.setName(newName);
							if (onPlayerChangedListener != null)
								onPlayerChangedListener.onNameChanged(playerinfo, oldName, newName);
						}
					}
				});
				editPlayerName.setOnEditorActionListener(new TextView.OnEditorActionListener() {

					@Override
					public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
						editPlayerName.clearFocus();
						editPlayerName.setFocusable(false);
						return false;
					}
				});
			}
			profileView = (ImageView) findViewById(R.id.iv_profile);
			profileView.setOnClickListener(this);
		} catch (Exception e) {
			Debug.error(e);
		}
		// --
		super.onFinishInflate();
	}

	public void setTooltipVisibility(boolean visible) {
		if (visible) {
			if (genderTip != null)
				genderTip.show();
			if (nameTip != null)
				nameTip.show();
			if (gearTip != null)
				gearTip.show();
		} else {
			if (genderTip != null)
				genderTip.hide();
			if (nameTip != null)
				nameTip.hide();
			if (gearTip != null)
				gearTip.hide();
		}
	}

	public void setProfilePicture(Bitmap bitmap) {
		super.setProfilePicture(bitmap);
		if (profileView != null) {
			// landscape
			if (bitmap != null && bitmap.getWidth() > bitmap.getHeight()) {
				profileView.getLayoutParams().width = getResources().getDimensionPixelSize(R.dimen.photo_long);
				profileView.getLayoutParams().height = getResources().getDimensionPixelSize(R.dimen.photo_short);
			} else { // portrait
				profileView.getLayoutParams().width = getResources().getDimensionPixelSize(R.dimen.photo_short);
				profileView.getLayoutParams().height = getResources().getDimensionPixelSize(R.dimen.photo_long);
			}

			if (bitmap != null) {
				profileView.setImageBitmap(bitmap);
			} else {
				profileView.setImageResource(R.drawable.profile_preview);
			}
			profileView.requestLayout();
		}
	}

	public void setProfilePictureVisibility(boolean visible) {
		if (visible) {
			profileView.setVisibility(View.VISIBLE);
			if (editPlayerName != null)
				editPlayerName.setTextSize(getResources().getInteger(R.integer.playerName_fontSize_small));
			if (playerClassRace != null)
				playerClassRace.setTextSize(getResources().getInteger(R.integer.playerRace_fontSize_small));

		} else {
			profileView.setVisibility(View.GONE);
			if (editPlayerName != null)
				editPlayerName.setTextSize(getResources().getInteger(R.integer.playerName_fontSize_large));
			if (playerClassRace != null)
				playerClassRace.setTextSize(getResources().getInteger(R.integer.playerRace_fontSize_large));

		}
	}

	public PlayerFragment getPlayerFragment() {
		return playerFragment;
	}

	public void setPlayerFragment(PlayerFragment playerFragment) {
		this.playerFragment = playerFragment;
	}

	public void setPlayerName(String name) {
		if (TextUtils.isEmpty(name))
			name = null;

		super.setPlayerName(name);

		if (editPlayerName != null && !TextUtils.equals(name, editPlayerName.getText()))
			editPlayerName.setText(name);

	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.munchlevel.view.BasePlayerLayout#setMale(boolean)
	 */
	@Override
	protected void setMale(boolean male) {

		boolean oldVal = getPlayerInfo().isMale();

		super.setMale(male);

		if (oldVal != male && getPlayerFragment().getOnPlayerChangedListener() != null) {
			getPlayerFragment().getOnPlayerChangedListener().onGenderChanged(playerinfo, oldVal, male);
		}

	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.munchlevel.view.BasePlayerLayout#setPlayerRace(java.lang.String[])
	 */
	@Override
	protected void setPlayerRace(List<String> race) {

		super.setPlayerRace(race);

		if (playerClassRace != null) {
			updateRaceString();
		}
	}

	protected void updateRaceString() {

		StringBuilder sb = new StringBuilder();
		List<String> race = getPlayerInfo().getRace();
		List<String> playerClass = getPlayerInfo().getClazz();

		sb.append(TextUtils.join(", ", race));
		sb.append(" / ");
		sb.append(TextUtils.join(", ", playerClass));

		if (playerClassRace != null) {
			playerClassRace.setText(sb.toString());
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.munchlevel.view.BasePlayerLayout#setPlayerClass(java.lang.String[])
	 */
	@Override
	protected void setPlayerClass(List<String> clazz) {

		super.setPlayerClass(clazz);

		if (playerClassRace != null) {
			updateRaceString();
		}
	}

	@Override
	public boolean onLongClick(View v) {

		if (v == gearCounter) {
			if (gearTip != null)
				gearTip.hide();
			return true;
		}

		return false;
	}

	@Override
	public void onClick(View v) {
		switch (v.getId()) {
		case R.id.gear_counter:
			if (gearTip != null)
				gearTip.hide();
			break;
		}

	}

}
